#include "StdAfx.h"
#include "FunctionObject.h"
#include "StackFrame.h"
#include "StackTrace.h"

StackTrace::StackTrace(CONTEXT& ctx)
{
	SymInitialize(GetCurrentProcess(), NULL, TRUE);
	STACKFRAME64 frFirst;
	frFirst.AddrPC.Offset = ctx.Eip;
	frFirst.AddrPC.Mode = AddrModeFlat;
	frFirst.AddrFrame.Offset = ctx.Ebp;
	frFirst.AddrFrame.Mode = AddrModeFlat;
	frFirst.AddrStack.Offset = ctx.Esp;
	frFirst.AddrStack.Mode = AddrModeFlat;

	m_frames.push_back(new StackFrame(frFirst));

	while(StackWalk64(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(), &frFirst, &ctx, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
	{
		StackFrame* frame = new StackFrame(frFirst);
		m_frames.push_back(frame);
		if(m_frames.size() >= 62)
			break;
	}
}

StackTrace::~StackTrace()
{
	for(UINT i = 0; i < m_frames.size(); ++i)
		delete m_frames[i];
}

std::ostream& operator << (std::ostream& strm, const StackTrace& trace)
{
	for(UINT i = 0; i < trace.m_frames.size(); ++i) {
		strm << trace.m_frames[i]->ToString() << std::endl;
	}
	return strm;
}